package tests;

import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.util.Iterator;
import java.util.List;

import junit.framework.TestCase;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InOrder;

/**
 * 一个独立的mockito测试，写明mock,when,verify,times方法的使用.
 * 
 * 仅供试用
 * 
 * @author Beanstao@gmail.com
 * 
 */
public class MockitoDemo extends TestCase
{
	private Iterator<String> iteratorMock;
	private List<String> listMock;

	@Override
	@SuppressWarnings("unchecked")
	@Before
	public void setUp()
	{
		iteratorMock = mock(Iterator.class);
		listMock = mock(List.class);
	}

	@Override
	@After
	public void tearDown()
	{
		iteratorMock = null;
		listMock = null;
	}

	@Test
	public void testMockito()
	{
		when(iteratorMock.next()).thenReturn("Hello ").thenReturn("World");

		String result = iteratorMock.next() + iteratorMock.next();
		verify(iteratorMock, times(2)).next();

		assertEquals("Hello World", result);
	}

	/**
	 * code.google官网代码
	 */
	@SuppressWarnings("unchecked")
	@Test
	public void testMockitoOrder()
	{
		// A. Single mock whose methods must be invoked in a particular order
		// using mocks
		listMock.add("was added first");
		listMock.add("was added second");
		// create an inOrder verifier for a single mock
		InOrder inOrder = inOrder(listMock);
		// following will make sure that add is first called with "was added first, then with "was added second"
		inOrder.verify(listMock).add("was added first");
		inOrder.verify(listMock).add("was added second");

		// B. Multiple mocks that must be used in a particular order
		List<String> firstMock = mock(List.class);
		List<String> secondMock = mock(List.class);

		// using mocks
		firstMock.add("was called first");
		secondMock.add("was called second");

		// create inOrder object passing any mocks that need to be verified in order
		InOrder inOrder2 = inOrder(firstMock, secondMock);

		// following will make sure that firstMock was called before secondMock
		inOrder2.verify(firstMock).add("was called first");
		inOrder2.verify(secondMock).add("was called second");

		// Oh, and A + B can be mixed together at will

	}

}
